/*
 * 功能：Web控制器，负责处理基础的HTTP请求
 * 作者：张杨(Sunny)
 * 日期： 2024/10/25 上午9:46
 */
package com.example.springboot.control;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.springboot.common.AuthAccess;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Car;
import com.example.springboot.entity.Reserve;
import com.example.springboot.entity.User;
import com.example.springboot.service.CarService;
import com.example.springboot.service.ReserveService;
import com.example.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * WebController 类是一个 Web的控制器，处理基础的 HTTP 请求
 */
@RestController
public class WebController {

    @Resource
    UserService userService;

    @Resource
    ReserveService reserveService;

    @Resource
    CarService carService;

    /**
     * 处理根路径的 GET 请求，返回成功信息
     *
     * @return 成功信息
     */
    @AuthAccess
    @GetMapping("/")
    public Result hello() {
        return Result.success("success");
    }

    /**
     * 处理用户登录的 POST 请求
     *
     * @param user 用户登录信息
     * @return 登录成功返回用户信息，否则返回错误信息
     */
    @PostMapping("/login")
    public Result login(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUsername())
                || StrUtil.isBlank(user.getPassword())) {
            return Result.error("数据输入不合法");
        }
        user = userService.login(user); // 调用用户服务进行登录验证
        return Result.success(user);
    }

    /**
     * 处理用户注册的 POST 请求
     *
     * @param user 用户注册信息
     * @return 注册成功返回用户信息，否则返回错误信息
     */
    @AuthAccess
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUsername())
                || StrUtil.isBlank(user.getPassword())
                || StrUtil.isBlank(user.getRole())) {
            return Result.error("数据不能为空");
        }
        if (user.getUsername().length() > 10 || user.getPassword().length() > 20) {
            return Result.error("用户名或密码过长"); // 检查用户名和密码长度是否符合要求
        }
        user = userService.register(user);
        return Result.success(user);
    }

    /**
     * 处理用户重置密码的 PUT 请求
     *
     * @param user 包含用户名和手机号的用户信息
     * @return 重置密码成功返回成功信息，否则返回错误信息
     */
    @AuthAccess
    @PutMapping("/password")
    public Result password(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPhone())) {
            return Result.error("数据输入不合法");
        }
        userService.resetPassword(user);
        return Result.success();
    }

    /**
     * 获取统计图数据
     *
     * @return 动态数据
     */
    @GetMapping("/chart")
    public Result chart() {
        // 获取当前年月
        LocalDate now = LocalDate.now();
        int currentYear = now.getYear();
        int currentMonth = now.getMonthValue();

        // 获取所有数据并过滤出当月数据
        List<Reserve> allReserves = reserveService.list();
        List<Reserve> currentMonthReserves = allReserves.stream()
                .filter(reserve -> reserve.getReserveTime() != null)
                .filter(reserve -> {
                    LocalDate reserveDate = reserve.getReserveTime().toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    return reserveDate.getYear() == currentYear
                            && reserveDate.getMonthValue() == currentMonth;
                })
                .collect(Collectors.toList());

        // 包装折线图数据 - 每日预约量
        Map<LocalDate, Long> dailyCount = currentMonthReserves.stream()
                .collect(Collectors.groupingBy(
                        reserve -> reserve.getReserveTime().toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDate(),
                        Collectors.counting()
                ));

        List<Dict> lineList = dailyCount.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> Dict.create()
                        .set("date", entry.getKey().toString())
                        .set("value", entry.getValue()))
                .collect(Collectors.toList());

        // 包装饼图数据 - 课程类型分布
        Map<String, Long> courseTypeCount = currentMonthReserves.stream()
                .filter(reserve -> "课程".equals(reserve.getType()))
                .filter(reserve -> "已通过".equals(reserve.getState()))
                .collect(Collectors.groupingBy(
                        Reserve::getDescription,
                        Collectors.counting()
                ));

        List<Dict> pieList = courseTypeCount.entrySet().stream()
                .map(entry -> Dict.create()
                        .set("name", entry.getKey())
                        .set("value", entry.getValue()))
                .collect(Collectors.toList());

        // 返回结果
        return Result.success(Dict.create()
                .set("line", lineList)
                .set("pie", pieList));
    }
    /**
     * 统计不同角色的用户、预约、车辆的数量
     * 返回学员、教练、管理员的数量，以及车辆预约和课程预约的数量
     *
     * @return 包含各种统计数据的Map
     */
    @GetMapping("/count")
    public Result count() {
        // 创建查询条件包装器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 统计学员数量
        queryWrapper.eq("role", "学员");
        queryWrapper.and(wrapper -> wrapper.ne("state", "已毕业").or().isNull("state"));
        long studentCurrentCount = userService.count(queryWrapper);
        // 重置查询条件
        queryWrapper.clear();
        // 统计教练数量
        queryWrapper.eq("role", "教练");
        long coachCount = userService.count(queryWrapper);
        // 重置查询条件
        queryWrapper.clear();
        // 统计管理员数量
        queryWrapper.eq("role", "管理员");
        long adminCount = userService.count(queryWrapper);
        // 重置查询条件
        queryWrapper.clear();


        QueryWrapper<Reserve> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("type", "车辆");
        queryWrapper1.eq("state", "已通过");
        queryWrapper1.ge("reserveTime", LocalDate.now());
        long reserveCarCount = reserveService.count(queryWrapper1);
        // 重置查询条件
        queryWrapper1.clear();

        queryWrapper1.eq("type", "课程");
        queryWrapper1.eq("state", "已通过");
        queryWrapper1.ge("reserveTime", LocalDate.now());
        long reserveCourseCount = reserveService.count(queryWrapper1);
        // 重置查询条件
        queryWrapper1.clear();

        // 创建查询条件包装器
        QueryWrapper<Car> queryWrapper2 = new QueryWrapper<>();
        queryWrapper1.eq("state", "可预约");
        long carCurrentCount = carService.count(queryWrapper2);
        // 重置查询条件
        queryWrapper1.clear();

        // 构建返回结果
        Map<String, Long> countMap = new HashMap<>();
        countMap.put("studentCurrentCount", studentCurrentCount);
        countMap.put("coachCount", coachCount);
        countMap.put("adminCount", adminCount);

        countMap.put("reserveCarCount", reserveCarCount);
        countMap.put("reserveCourseCount", reserveCourseCount);

        countMap.put("carCurrentCount", carCurrentCount);

        return Result.success(countMap);
    }
}